/*
 * Version: MPL 1.1
 *
 * "The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * The Original Code is ICEfaces 1.5 open source software code, released
 * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
 * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
 * 2004-2010 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 *
 * Contributor(s): _____________________.
 *
 */
package br.com.eurotrader.utils;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
 * JSF utilities.
 *
 * @author ICEsoft Technologies Inc.
 * @since 2.0
 */
public class FacesUtils {

    private static Properties buildProperties = null;

    /**
     * Get servlet context.
     *
     * @return the servlet context
     */
    public static ServletContext getServletContext() {
        return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    }

    public static ExternalContext getExternalContext() {
        FacesContext fc = FacesContext.getCurrentInstance();
        return fc.getExternalContext();
    }

    public static HttpSession getHttpSession(boolean create) {
        return (HttpSession) FacesContext.getCurrentInstance().
                getExternalContext().getSession(create);
    }

    /**
     * Get managed bean based on the bean name.
     *
     * @param beanName the bean name
     * @return the managed bean associated with the bean name
     */
    public static Object getManagedBean(String beanName) {
        FacesContext fc = FacesContext.getCurrentInstance();
        ELContext elc = fc.getELContext();
        ExpressionFactory ef = fc.getApplication().getExpressionFactory();
        ValueExpression ve = ef.createValueExpression(elc, getJsfEl(beanName), Object.class);
        return ve.getValue(elc);
    }

    /**
     * Remove the managed bean based on the bean name.
     *
     * @param beanName the bean name of the managed bean to be removed
     */
    public static void resetManagedBean(String beanName) {
        FacesContext fc = FacesContext.getCurrentInstance();
        ELContext elc = fc.getELContext();
        ExpressionFactory ef = fc.getApplication().getExpressionFactory();
        ef.createValueExpression(elc, getJsfEl(beanName),
                Object.class).setValue(elc, null);
    }

    /**
     * Store the managed bean inside the session scope.
     *
     * @param beanName    the name of the managed bean to be stored
     * @param managedBean the managed bean to be stored
     */
    public static void setManagedBeanInSession(String beanName, Object managedBean) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(beanName, managedBean);
    }

    /**
     * Store the managed bean inside the request scope.
     *
     * @param beanName    the name of the managed bean to be stored
     * @param managedBean the managed bean to be stored
     */
    public static void setManagedBeanInRequest(String beanName, Object managedBean) {
        FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(beanName, managedBean);
    }

    /**
     * Get parameter value from request scope.
     *
     * @param name the name of the parameter
     * @return the parameter value
     */
    public static String getRequestParameter(String name) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
    }

    /**
     * Get named request map object value from request map.
     *
     * @param name the name of the key in map
     * @return the key value if any, null otherwise.
     */
    public static Object getRequestMapValue(String name) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(name);
    }

    /**
     * Gets the action attribute value from the specified event for the given
     * name.  Action attributes are specified by &lt;f:attribute /&gt;.
     *
     * @param event
     * @param name
     * @return
     */
    public static String getActionAttribute(ActionEvent event, String name) {
        return (String) event.getComponent().getAttributes().get(name);
    }

    public static String getBuildAttribute(String name) {
        if (buildProperties != null) {
            return buildProperties.getProperty(name, "unknown");
        }
        InputStream is = null;
        try {
            is = getServletContext().getResourceAsStream("/WEB-INF/buildversion.properties");
            buildProperties = new java.util.Properties();
            buildProperties.load(is);
        } catch (Throwable e) {
            is = null;
            buildProperties = null;
            return "unknown";
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Throwable t) {
                }
            }
        }
        return buildProperties.getProperty(name, "unknown");
    }

    /**
     * Gest parameter value from the the session scope.
     *
     * @param name name of the parameter
     * @return the parameter value if any.
     */
    public static String getSessionParameter(String name) {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest myRequest = (HttpServletRequest) context.getExternalContext().getRequest();
        HttpSession mySession = myRequest.getSession();
        return myRequest.getParameter(name);
    }

    /**
     * Get parameter value from the web.xml file
     *
     * @param parameter name to look up
     * @return the value of the parameter
     */
    public static String getFacesParameter(String parameter) {
        // Get the servlet context based on the faces context
        ServletContext sc = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

        // Return the value read from the parameter
        return sc.getInitParameter(parameter);
    }

    /**
     * Add information message.
     *
     * @param msg the information message
     */
    public static void addInfoMessage(String msg) {
        addInfoMessage(null, msg);
    }

    /**
     * Add information message to a specific client.
     *
     * @param clientId the client id
     * @param msg      the information message
     */
    public static void addInfoMessage(String clientId, String msg) {
        FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
    }

    /**
     * Add information message to a specific client.
     *
     * @param clientId the client id
     * @param msg      the information message
     */
    public static void addWarnMessage(String clientId, String msg) {
        FacesContext.getCurrentInstance().addMessage(clientId,
                new FacesMessage(FacesMessage.SEVERITY_WARN, msg, msg));
    }

    /**
     * Add error message.
     *
     * @param msg the error message
     */
    public static void addErrorMessage(String msg) {
        addErrorMessage(null, msg);
    }

    /**
     * Finds component with the given id
     *
     * @param c  component check children of.
     * @param id id of component to search for.
     * @return found component if any.
     */
    public static UIComponent findComponent(UIComponent c, String id) {
        if (id.equals(c.getId())) {
            return c;
        }
        Iterator<UIComponent> kids = c.getFacetsAndChildren();
        while (kids.hasNext()) {
            UIComponent found = findComponent(kids.next(), id);
            if (found != null) {
                return found;
            }
        }
        return null;
    }

    /**
     * Finds all component with the given id.  Component id's are formed from
     * the concatination of parent component ids.  This search will find
     * all componet in the component tree with the specified id as it is possible
     * to have the same id used more then once in the component tree
     *
     * @param root            component check children of.
     * @param id              id of component to search for.
     * @param foundComponents list of found component with the specified id.
     * @return found component if any.
     */
    public static void findAllComponents(UIComponent root, String id,
            List<UIComponent> foundComponents) {
        if (id.equals(root.getId())) {
            foundComponents.add(root);
        }
        Iterator<UIComponent> kids = root.getFacetsAndChildren();
        while (kids.hasNext()) {
            findAllComponents(kids.next(), id, foundComponents);
        }
    }

    /**
     * Add error message to a specific client.
     *
     * @param clientId the client id
     * @param msg      the error message
     */
    public static void addErrorMessage(String clientId, String msg) {
        FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
    }

    private static String getJsfEl(String value) {
        return "#{" + value + "}";
    }

    //ParÃ¢metros:
    /**      *    1 - Valor a arredondar.
     *    2 - Quantidade de casas depois da vÃ­rgula.
     *  3 - Arredondar para cima ou para baixo?
     *        Para cima = 0 (ceil)
     *        Para baixo = 1 ou qualquer outro inteiro (floor)
     **/
    public static BigDecimal arredonda(BigDecimal valor) {
        if (valor != null) {
            return valor.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return valor;
    }

    public static Double arredonda(Double valor) {
        if (valor != null) {
            return new BigDecimal(valor).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            return valor;
        }
    }
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    public static Date retornaDataAtual() {
        try {
            return sdf.parse(sdf.format(Calendar.getInstance().getTime()));
        } catch (ParseException ex) {
            // Logger.getLogger(FuncoesGerais.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("!!!!! ERRO NA FUNção QUE RETORNA A DATA ATUAL(FacesUtils.java) !!!!!!");
        return null;
    }

    public static String retornaDataFormatada(Date data) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("dd/MM/yyyy");
        return sdf1.format(data);
    }
    
    public static String retornaDataFormatadaTracos(Date data) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
        return sdf1.format(data);
    }

    public static String retornaDataHoraFormatada(Date data) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("dd/MM/yyyy HH:mm");
        return sdf1.format(data);
    }
    
    public static String retornaHoraFormatada(Date data) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
        return sdf1.format(data);
    }

    public static String retornaDoubleFormatado(Double valor) {
        if (valor != null) {
            DecimalFormat formatador;
            formatador = new DecimalFormat("#,###,###,###,##0.00");
            formatador.setGroupingUsed(true);
            return formatador.format(valor);
        } else {
            return "";
        }

    }


    /* Arredonda um valor com o numero de decimais especificado */
    public static double round(double value, int decimais) {
        double p = Math.pow(10, decimais);
        return Math.round(value * p) / p;
    }

    //Data anterior a data posterior, igual retorna false;
    public static boolean validaIntervaloDeDatas(Date dataQueDeveSerMaiorOuIgual, Date dataBase) {
        if (dataBase == null) {
            dataBase = retornaDataAtual();
        }
        if ((dataBase != null) && (dataQueDeveSerMaiorOuIgual != null)) {
            Calendar calDataComparar = Calendar.getInstance();
            calDataComparar.setTime(dataQueDeveSerMaiorOuIgual);
            Calendar dataQueDeveSerMaiorOuIgualConfig = new GregorianCalendar(calDataComparar.get(Calendar.YEAR), calDataComparar.get(Calendar.MONTH), calDataComparar.get(Calendar.DATE));
            Calendar calDataBase = Calendar.getInstance();
            calDataBase.setTime(dataBase);
            Calendar dataBaseConfig = new GregorianCalendar(calDataBase.get(Calendar.YEAR), calDataBase.get(Calendar.MONTH), calDataBase.get(Calendar.DATE));
            if (dataQueDeveSerMaiorOuIgualConfig.before(dataBaseConfig)) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }
}